﻿using System;
using System.Text;
using System.Security.Cryptography;
using System.Web.Security;
using System.IO;

namespace Lin.Library.Extensions
{
    public static class SecurityExt
    {
        #region 静态方法
        /// <summary>
        /// 普通哈希
        /// </summary>
        public static String ObjectToHash(object source)
        {
            if (source == null)
            {
                return String.Empty;
            }

            string sre = source.ToString();

            if (String.IsNullOrEmpty(sre))
            {
                return String.Empty;
            }

            MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = Encoding.ASCII.GetBytes(sre);
            byte[] hash = md5.ComputeHash(inputBytes);

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("x2"));
            }
            return sb.ToString();
        }

        /// <summary>
        /// SHA1哈希
        /// </summary>
        public static String ObjectToSHA1Hash(object source)
        {
            if (source == null)
            {
                return String.Empty;
            }

            string sre = source.ToString();

            if (String.IsNullOrEmpty(sre))
            {
                return String.Empty;
            }

            return FormsAuthentication.HashPasswordForStoringInConfigFile(sre, "SHA1");
        }

        /// <summary>
        /// 加密
        /// </summary>
        public static String ObjectToEncrypt(object source)
        {
            if (source == null)
            {
                return String.Empty;
            }

            string sre = source.ToString();

            if (String.IsNullOrEmpty(sre))
            {
                return String.Empty;
            }

            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = Encoding.Default.GetBytes(sre);

            des.Key = ASCIIEncoding.ASCII.GetBytes("JerryLin");
            des.IV = ASCIIEncoding.ASCII.GetBytes("JerryLin");

            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);

            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();

            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }

            return ret.ToString();
        }

        /// <summary>
        /// 解密
        /// </summary>
        public static String ObjectToDecrypt(object source)
        {
            if (source == null)
            {
                return String.Empty;
            }

            string sre = source.ToString();

            if (String.IsNullOrEmpty(sre))
            {
                return String.Empty;
            }

            try
            {

                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                byte[] inputByteArray = new byte[sre.Length / 2];
                for (int x = 0; x < sre.Length / 2; x++)
                {
                    int i = (Convert.ToInt32(sre.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                }
                des.Key = ASCIIEncoding.ASCII.GetBytes("JerryLin");
                des.IV = ASCIIEncoding.ASCII.GetBytes("JerryLin");

                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);

                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();

                return Encoding.ASCII.GetString(ms.ToArray());
            }
            catch
            { 
                
            }

            return string.Empty;
        }

        /// <summary>
        /// RSA加密
        /// </summary>
        public static String ObjectToRsaEncrypt(object source)
        {
            if (source == null)
            {
                return String.Empty;
            }

            string sre = source.ToString();

            if (String.IsNullOrEmpty(sre))
            {
                return String.Empty;
            }

            CspParameters csp = new CspParameters();
            csp.KeyContainerName = "Lin";

            RSACryptoServiceProvider RSAProvider = new RSACryptoServiceProvider(csp);
            byte[] encryptBytes = RSAProvider.Encrypt(ASCIIEncoding.ASCII.GetBytes(sre), true);

            StringBuilder str = new StringBuilder();
            foreach (byte b in encryptBytes)
            {
                str.AppendFormat("{0:x2}", b);
            }
            return str.ToString();
        }
        
        /// <summary>
        /// RSA解密
        /// </summary>
        public static String ObjectToRsaDecrypt(object source)
        {
            if (source == null)
            {
                return String.Empty;
            }

            string sre = source.ToString();

            if (String.IsNullOrEmpty(sre))
            {
                return String.Empty;
            }

            CspParameters csp = new CspParameters();
            csp.KeyContainerName = "Lin";
            RSACryptoServiceProvider RSAProvider = new RSACryptoServiceProvider(csp);
            int length = (sre.Length / 2);
            byte[] decryptBytes = new byte[length];
            for (int index = 0; index < length; index++)
            {
                string substring = sre.Substring(index * 2, 2);
                decryptBytes[index] = Convert.ToByte(substring, 16);
            }
            decryptBytes = RSAProvider.Decrypt(decryptBytes, true);
            return ASCIIEncoding.ASCII.GetString(decryptBytes);
        }

        #endregion

        #region 扩展方法

        /// <summary>
        /// 普通哈希
        /// </summary>
        public static String ToHash(this object source)
        {
            return ObjectToHash(source);
        }

        /// <summary>
        /// SHA1哈希
        /// </summary>
        public static String ToSHA1Hash(this object source)
        {
            return ObjectToSHA1Hash(source);
        }

        /// <summary>
        /// 加密
        /// </summary>
        public static String ToEncrypt(this object source)
        {
            return ObjectToEncrypt(source);
        }

        /// <summary>
        /// 解密
        /// </summary>
        public static String ToDecrypt(this object source)
        {
            return ObjectToDecrypt(source);
        }

        /// <summary>
        /// RSA加密
        /// </summary>
        public static String ToRsaEncrypt(this object source)
        {
            return ObjectToRsaEncrypt(source);
        }

        /// <summary>
        /// RSA解密
        /// </summary>
        public static String ToRsaDecrypt(this object source)
        {
            return ObjectToRsaDecrypt(source);
        }

        #endregion
    }
}
